import tornado.web

"""
class MainHandler(tornado.web.RequestHandler):
    def get(self):
        self.write('Hello, SELECT\n')

    def post(self):
        self.write('Hello, ADD\n')

    def put(self):
        self.write('Hello, UPDATE\n')

    def delete(selft):
        self.write('Hello, DELETE\n')
from tornado.tcpserver import TCPServer
from tornado import gen
from pyrestful import mediatypes
from pyrestful.rest import get, post, put, delete
import logging
class MyTcpServer(TCPServer) :
    def __init__(self, io_loop=None, **kwargs):
        TCPServer.__init__(self, io_loop, **kwargs)

    @gen.coroutine
    def handle_stream(self, stream, address):
        try:
            while True:
                msg = yield stream.read_bytes(20, partial = True)
                print(msg, 'from', address)
                stream.write(str(msg))
                yield stream.write(msg[::-1])
                if 'over' == msg:
                    stream.close()
        except iostream.StreamClosedError:
            pass

class MyRestfulHandler(pyrestful.rest.RestHandler) :
    def __init__(self):
        loggerRoot = logging.getLogger('root')
        loggerRoot.debug('Start MyResufulHandler Modulei.')

    @get(_path='/customer/{id_customer}',
        _types=[int],
        _produces=mediatypes.APPLICATION_JSON)
    def getTest(self, id_customer):
        try:
            response = dict()
            response['id_customer'] = id_customer
            return response
        except Exception(ex):
            pass
if '__main__' == __name__ :
    activate_this = 'default/bin/activate_this.py'
    exec(open(activate_this).read(), {'__file__':activate_this})
    print('virtualenv \'default\' loaded.')

    
    settings = {
        'debug' : True,
        'static_path' : os.path.join(os.path.dirname(__file__), "static"),
        'template_path' : os.path.join(os.path.dirname(__file__), "template")
    }
    application = tornado.web.Application(
        [(r"/", RestHandler)a)]
        #**settings)
    application.listen(8888)
    ioloop.IOLoop.instance().start()
"""

    #from MyTcpServer import *
    #server = MyTcpServer()
    #server.listen(8080)
    #server.start()
    #ioloop.IOLoop.current().start()

import os
import json
from tornado import ioloop, web, gen

class Command:
    Login = 0x01
    Logout = 0x03
    UpdateToken = 0x03
    KeepAlive = 0x04
    LastChanges = 0x05
    LastInsertRowID = 0x06
    Interrupt = 0x07
    LibVersion = 0x08
    Exec = 0x09
    FetchTable = 0x0A
    Prepare = 0x0B
    PrepareExec = 0x0C
    PrepareFetchTable = 0x0D
    SubscribeQuery = 0x0E
    UnsubscribeQuery = 0x0F
    Pull = 0x10

    class ConstError(TypeError):
        pass

    def __setattr__(self, name, value):
        if name in self.__dict__:
            raise self.ConstError("Can't rebind const (%s)" % name)
        self.__dict__[name]=value


class DataType:
    Integer = 0x00
    Double = 0x01
    String = 0x02

    class ConstError(TypeError):
        pass

    def __setattr__(self, name, value):
        if name in self.__dict__:
            raise self.ConstError("Can't rebind const (%s)" % name)
        self.__dict__[name]=value


class JSONHandler(tornado.web.RequestHandler):
    def readAndDecode(self):
        return json.loads(self.request.body);

    def encodeAndWrite(self, obj):
        self.write(json.dumps(obj));


class CmdLoginHandler(JSONHandler):
    @gen.coroutine
    def get(self):
        yield self.post()

    @gen.coroutine
    def post(self):
        obj = {
            'seqNo': 17780,
            'cmd': Command.Login,
            'token': 44
        }
        self.encodeAndWrite(obj)


class CmdLogoutHandler(JSONHandler):
    @gen.coroutine
    def get(self):
        yield self.post()

    @gen.coroutine
    def post(self):
        obj = {
            'seqNo': 65531,
            'cmd': Command.Logout
        }
        self.encodeAndWrite(obj)

class CmdUpdateTokenHandler(JSONHandler):
    @gen.coroutine
    def get(self):
        yield self.post()

    @gen.coroutine
    def post(self):
        obj = {
            'seqNo': 56531,
            'cmd': Command.UpdateToken,
            'token': 44
        }
        self.encodeAndWrite(obj)

class CmdKeepAliveHandler(JSONHandler):
    @gen.coroutine
    def get(self):
        yield self.post()

    @gen.coroutine
    def post(self):
        obj = {
            'seqNo': 34712,
            'cmd': Command.KeepAlive
        }
        self.encodeAndWrite(obj)

class CmdLastChangesHandler(JSONHandler):
    @gen.coroutine
    def get(self):
        yield self.post()

    @gen.coroutine
    def post(self):
        obj = {
            'seqNo': 56453,
            'cmd': Command.LastChanges,
            'count': 5
        }
        self.encodeAndWrite(obj)

class CmdLastInsertRowIdHandler(JSONHandler):
    @gen.coroutine
    def get(self):
        self.post()

    @gen.coroutine
    def post(self):
        obj = {
            'seqNo': 32124,
            'cmd': Command.LastInsertRowID,
            'rowId': 3

        }
        self.encodeAndWrite(obj)

class CmdInterruptHandler(JSONHandler):
    @gen.coroutine
    def get(self):
        self.post()

    @gen.coroutine
    def post(self):
        obj = {
            'seqNo': 123,
            'cmd': Command.Interrupt
        }
        self.encodeAndWrite(obj)

class CmdLibVersionHandler(JSONHandler):
    @gen.coroutine
    def get(self):
        self.post()

    @gen.coroutine
    def post(self):
        obj = {
            'seqNo': 6579,
            'cmd': Command.LibVersion,
            'version': 'sqlite 3.7.1.2'
        }
        self.encodeAndWrite(obj)

class CmdExecHandler(JSONHandler):
    @gen.coroutine
    def get(self):
        self.post()

    @gen.coroutine
    def post(self):
        obj = {
            'seqNo': 13303,
            'cmd': CommandExec
        }
        self.encodeAndWrite(obj)

class CmdFetchTableHandler(JSONHandler):
    @gen.coroutine
    def get(self):
        self.post()

    @gen.coroutine
    def post(self):
        obj = {
            'seqNo': 1453,
            'cmd': Command.FetchTable,
            'colCount': 5,
            'cols': ['a', 'b', 'c', 'd', 'e'],
            'colsType': [DataType.Integer, DataType.Integer, DataType.Integer, DataType.Integer, DataType.Integer],
            'rowCount': 3,
            'rows': [
                [1, 2, 3, 4, 5],
                [6, 7, 8, 9, 0],
                [1, 5, 3, 2, 7]
            ]

        }
        self.encodeAndWrite(obj)

class CmdPrepareHandler(JSONHandler):
    @gen.coroutine
    def get(self):
        self.post()

    @gen.coroutine
    def post(self):
        obj = {
            'seqNo': 19665,
            'cmd': Command.Prepare,
            'preparedId': 996

        }
        self.encodeAndWrite(obj)

class CmdPrepareExecHandler(JSONHandler):
    @gen.coroutine
    def get(self):
        yield self.post()

    @gen.coroutine
    def post(self):
        obj = {
            'seqNo': 19665,
            'cmd': Command.PrepareExec
        }
        self.encodeAndWrite(obj)


class CmdPrepareFetchTableHandler(JSONHandler):
    @gen.coroutine
    def get(self):
        yield self.post()

    @gen.coroutine
    def post(self):
        obj = {
            'cmd': Command.PrepareFetchTable,
            'colCount': 5,
            'cols': ['a', 'b', 'c', 'd', 'e'],
            'colsType': [DataType.Integer, DataType.Integer, DataType.Integer, DataType.Integer, DataType.Integer],
            'rowCount': 3,
            'rows': [
                [1, 2, 3, 4, 5],
                [6, 7, 8, 9, 0],
                [1, 5, 3, 2, 7]
            ]
        }
        self.encodeAndWrite(obj)


class CmdSubscribeQueryHandler(JSONHandler):
    @gen.coroutine
    def get(self):
        yield self.post()

    @gen.coroutine
    def post(self):
        obj = {
            'seqNo': 19665,
            'cmd': Command.SubscribeQuery,
            'subscribedId': 15
        }
        self.encodeAndWrite(obj);

class CmdUnsubscribeQueryHandler(JSONHandler):
    @gen.coroutine
    def get(self):
        yield self.post()

    @gen.coroutine
    def post(self):
        obj = {
            'seqNo': 19665,
            'cmd': Command.UnsubscribeQuery
        }
        self.encodeAndWrite(obj);


class CmdPullHandler(JSONHandler):
    @gen.coroutine
    def get(self):
        yield self.post()
        #a = {'ret' : 1}
        #self.encodeAndWrite(a)
        #self.write('It works!CmdPull')

    @gen.coroutine
    def post(self):
        obj = {
            'seqNo': 19665,
            'cmd': Command.Pull,
            'reports':[{
            	'colCount': 5,
            	'cols': ['a', 'b', 'c', 'd', 'e'],
            	'colsType': [DataType.Integer, DataType.Integer, DataType.Integer, DataType.Integer, DataType.Integer],
            	'rowCount': 3,
            	'rows': [
            	    [1, 2, 3, 4, 5],
            	    [6, 7, 8, 9, 0],
            	    [1, 5, 3, 2, 7]
            ]}, {
            	'colCount': 5,
            	'cols': ['a', 'b', 'c', 'd', 'e'],
            	'colsType': [DataType.Integer, DataType.Integer, DataType.Integer, DataType.Integer, DataType.Integer],
            	'rowCount': 3,
            	'rows': [
            	    [1, 2, 3, 4, 5],
            	    [6, 7, 8, 9, 0],
            	    [1, 5, 3, 2, 7]
           ]}]
        }
        self.encodeAndWrite(obj)

def main():
    settings = {
        'debug' : True,
        'static_path' : os.path.join(os.path.dirname(__file__), "static"),
        'template_path' : os.path.join(os.path.dirname(__file__), "template")
    }
    application = tornado.web.Application(
        [
            (r"/CmdLogin", CmdLoginHandler),
            (r"/CmdLogout", CmdLogoutHandler),
            (r"/CmdUpdateToken", CmdUpdateTokenHandler),
            (r"/CmdKeepAlive", CmdKeepAliveHandler),
            (r"/CmdLastChanges", CmdLastChangesHandler),
            (r"/CmdLastInsertRowId", CmdLastInsertRowIdHandler),
            (r"/CmdInterrupt", CmdInterruptHandler),
            (r"/CmdLibVersion", CmdLibVersionHandler),
            (r"/CmdExec", CmdExecHandler),
            (r"/CmdFetchTable", CmdFetchTableHandler),
            (r"/CmdPrepare", CmdPrepareHandler),
            (r"/CmdPrepareExec", CmdPrepareExecHandler),
            (r"/CmdPrepareFetchTable", CmdPrepareFetchTableHandler),
            (r"/CmdSubscribeQuery", CmdSubscribeQueryHandler),
            (r"/CmdUnsubscribeQuery", CmdUnsubscribeQueryHandler),
            (r"/CmdPull", CmdPullHandler)
        ])
    application.listen(8080)
    ioloop.IOLoop.instance().start()

